home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / util / arc / xadmasterdev.lha / xad / Sources / tools / exe2arc.c next >
Encoding:
C/C++ Source or Header  |  2002-08-20  |  16.1 KB  |  622 lines

  1. #define NAME         "exe2arc"
  2. #define DISTRIBUTION "(Freeware) "
  3. #define REVISION     "5"
  4. #define DATE         "24.04.2002"
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        exe2arc
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    strips executable header from exe files
  12.     Compileropts:    -
  13.     Linkeropts:    -gsi -l amiga
  14.  
  15.  1.0   02.11.99 : first version
  16.  1.1   06.11.99 : now also supports zip exes with wrong offsets
  17.  1.2   29.05.00 : renamed from exe2zip, added Ace, Rar, Cab, Arj, LhA
  18.  1.3   07.07.00 : added TYPE keyword to specify archive type
  19.  1.4   15.09.01 : supports directories as destination as well
  20.  1.5   24.04.02 : fixed Enforcer hit
  21. */
  22.  
  23. #include <proto/exec.h>
  24. #include <proto/dos.h>
  25. #include <exec/memory.h>
  26. #include "SDI_version.h"
  27. #define SDI_TO_ANSI
  28. #include "SDI_ASM_STD_protos.h"
  29.  
  30. struct DosLibrary *     DOSBase = 0;
  31. struct ExecBase *     SysBase  = 0;
  32.  
  33. #define PARAM    "FROM/A,TO,TYPE/K"
  34.  
  35. struct Args {
  36.   STRPTR   from;
  37.   STRPTR   to;
  38.   STRPTR   type;
  39. };
  40.  
  41. #define BUFSIZE 102400
  42.  
  43. #define EndConvI32(a)    (((a)>>24)|(((a)>>8)&0xFF00)|(((a)<<8)&0xFF0000)|((a)<<24))
  44. #define EndConvI16(a)    ((UWORD)(((a)>>8)|((a)<<8)))
  45.  
  46. typedef BOOL (* SCANFUNC)(BPTR infh, STRPTR buffer, ULONG filesize, ULONG buffersize);
  47. typedef ULONG (* EXTRACTFUNC)(BPTR infh, BPTR outfh, STRPTR buffer, ULONG filesize, ULONG buffersize);
  48.  
  49. struct ScanData {
  50.   SCANFUNC    ScanFunc;
  51.   EXTRACTFUNC    ExtractFunc;
  52.   STRPTR    Extension; /* and type specifier */
  53.   STRPTR    Name; /* and type specifier */
  54. };
  55.  
  56. /* a) It is not the very best method to do scan loop again and again, but easy
  57.       to implement :-)
  58.    b) The buffer can be used to pass data from scanner to extractor.
  59. */
  60.  
  61. struct ScanData ScanFuncs[]; /* declaration, real field see file end */
  62.  
  63. ULONG start(void)
  64. {
  65.   ULONG ret = RETURN_FAIL;
  66.   struct DosLibrary *dosbase;
  67.  
  68.   SysBase = (*((struct ExecBase **) 4));
  69.   { /* test for WB and reply startup-message */
  70.     struct Process *task;
  71.     if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  72.     {
  73.       WaitPort(&task->pr_MsgPort);
  74.       Forbid();
  75.       ReplyMsg(GetMsg(&task->pr_MsgPort));
  76.       return RETURN_FAIL;
  77.     }
  78.   }
  79.  
  80.   if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  81.   {
  82.     struct Args args;
  83.     struct RDArgs *rda;
  84.  
  85.     DOSBase = dosbase;
  86.  
  87.     args.to = args.type = 0;
  88.     if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  89.     {
  90.       BPTR infh;
  91.  
  92.       if((infh = Open(args.from, MODE_OLDFILE)))
  93.       {
  94.         struct FileInfoBlock *fib;
  95.  
  96.         if((fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)))
  97.         {
  98.           if(ExamineFH(infh, fib))
  99.           {
  100.             STRPTR buf, name = args.to;
  101.  
  102.             if((buf = AllocMem(BUFSIZE+1024, MEMF_ANY)))
  103.             {
  104.           ULONG i, j;
  105.           LONG stop = 0, found = 0;
  106.  
  107.           for(i = 0; !stop && ScanFuncs[i].ScanFunc; ++i)
  108.           {
  109.         if(args.type && stricmp(ScanFuncs[i].Extension, args.type) && stricmp(ScanFuncs[i].Name, args.type))
  110.           ; /* skip the entry */
  111.                 else if(Seek(infh, 0, OFFSET_BEGINNING) >= 0)
  112.                 {
  113.           if(args.type)
  114.             found = 1;
  115.                   Printf("Scanning for %s-Archive.", ScanFuncs[i].Name);
  116.                   Flush(Output());
  117.                   if(ScanFuncs[i].ScanFunc(infh, buf, fib->fib_Size, BUFSIZE))
  118.                   {
  119.                     BPTR outfh;
  120.                     STRPTR tmp = buf+BUFSIZE;
  121.                     ULONG k;
  122.  
  123.                     if(!args.to) name = tmp;
  124.                     for(j = 0; args.from[j]; ++j)
  125.                       tmp[j] = args.from[j];
  126.                     k = j;
  127.  
  128.             do
  129.             {
  130.               if(tmp[--j] == '.')
  131.                 k = j;
  132.             } while(j && tmp[j] != '.' && tmp[j] != '/' && tmp[j] != ':');
  133.             tmp[k++] = '.';
  134.             for(j = 0; ScanFuncs[i].Extension[j]; ++j)
  135.               tmp[k++] = ScanFuncs[i].Extension[j];
  136.             tmp[k] = 0;
  137.                     stop = 1;
  138.             Printf(" Found.\n");
  139.                     if(!(outfh = Open(name, MODE_NEWFILE)) && args.to)
  140.                     {
  141.                       name = buf+BUFSIZE+512;
  142.                       *name = 0;
  143.                       AddPart(name, args.to, 512);
  144.                       tmp = buf+BUFSIZE; k = 0;
  145.                       for(j = 0; tmp[j]; ++j)
  146.                       {
  147.                         if(tmp[j] == '/' || tmp[j] == ':')
  148.                           k = j+1;
  149.                       }
  150.                       AddPart(name, tmp+k, 512);
  151.                       outfh = Open(name, MODE_NEWFILE);
  152.                     }
  153.                     if(outfh)
  154.                     {
  155.                       if((j = ScanFuncs[i].ExtractFunc(infh, outfh, buf, fib->fib_Size, BUFSIZE)))
  156.                       {
  157.                         Printf("Saved %ld byte to %s\nBe careful and test the file for correctness.\n", j, name);
  158.                         ret = 0;
  159.                       }
  160.                       Close(outfh);
  161.                       if(ret)
  162.                         DeleteFile(name);
  163.                     }
  164.                     else
  165.                       Printf("\nFailed to open output file.\n");
  166.                   }
  167.                   else
  168.                   {
  169.                     Printf("\r\033[K");
  170.                     Flush(Output());
  171.                   }
  172.                 }
  173.                 else
  174.                 {
  175.                   stop = 1;
  176.                   Printf("Failed to seek to file start.\n");
  177.                 }
  178.               }
  179.               if(!stop)
  180.               {
  181.                 if(args.type)
  182.                 {
  183.                   Printf("\r\033[KDid not find archive of type '%s'.\n", args.type);
  184.                   if(found)
  185.                     Printf("Maybe it is an archive of another type?\n");
  186.                   Printf("Valid types are: ");
  187.                   for(i = 0; !stop && ScanFuncs[i].ScanFunc; ++i)
  188.                     Printf("%s (%s)%s", ScanFuncs[i].Extension, ScanFuncs[i].Name, ScanFuncs[i+1].ScanFunc ? ", " : "\n");
  189.                 }
  190.                 else
  191.                   Printf("\r\033[KDid not find archive data.\n");
  192.               }
  193.               FreeMem(buf, BUFSIZE+1024);
  194.             }
  195.             else
  196.               Printf("Failed to open temporary buffer.\n");
  197.           }
  198.           else
  199.             Printf("Failed to examine file.\n");
  200.           FreeDosObject(DOS_FIB, 0);
  201.         }
  202.         else
  203.           Printf("Failed to open file information object.\n");
  204.         Close(infh);
  205.       }
  206.       else
  207.         Printf("Failed to open input file.\n");
  208.       FreeArgs(rda);
  209.     }
  210.     else
  211.       PrintFault(IoErr(), 0);
  212.     CloseLibrary((struct Library *) dosbase);
  213.   } /* OpenLibrary dos */
  214.   return ret;
  215. }
  216.  
  217. ULONG DoCopy(BPTR infh, BPTR outfh, STRPTR buf, ULONG size, ULONG buffersize)
  218. {
  219.   ULONG s, err = 0;
  220.   
  221.   while(size && !err)
  222.   {
  223.     s = size;
  224.     if(s > buffersize)
  225.       s = buffersize;
  226.     if(Read(infh, buf, s) != s)
  227.       err = RETURN_FAIL;
  228.     else if(Write(outfh, buf, s) != s)
  229.       err = RETURN_FAIL;
  230.     size -= s;
  231.   }
  232.   
  233.   return err;
  234. }
  235.  
  236. /******** exe2zip *********/
  237.  
  238. BOOL ScanZIP(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  239. {
  240.   ULONG start = 0, corr = 0;
  241.   LONG stop = 0, i, j, k;
  242.  
  243.   if(Seek(fh, 0, OFFSET_END) >= 0)
  244.   {
  245.     while(size > 22 && !stop)
  246.     {
  247.       if(bufsize > size)
  248.         bufsize = size;
  249.       if(Seek(fh, size-bufsize, OFFSET_BEGINNING) < 0)
  250.         ++stop;
  251.       else if(Read(fh, buf, bufsize) != bufsize)
  252.         ++stop;
  253.       for(i = bufsize-22; i >= 0 && !stop; --i)
  254.       {
  255.         if(buf[i] == 'P' && buf[i+1] == 'K' && buf[i+2] == 5 && buf[i+3] == 6)
  256.         {
  257.           j = (((((buf[i+19]<<8)+buf[i+18])<<8)+buf[i+17])<<8)+buf[i+16];
  258.           k = (((((buf[i+15]<<8)+buf[i+14])<<8)+buf[i+13])<<8)+buf[i+12];
  259.           if(j != size-bufsize+i-k)
  260.       {
  261.         corr = (size-bufsize+i-k)-j;
  262.         j += corr;
  263.       }
  264.           if(Seek(fh, j+4, OFFSET_BEGINNING) >= 0)
  265.           {
  266.             if(Read(fh, buf, 42) == 42)
  267.               start = ((buf[38]) | (buf[39]<<8) | (buf[40]<<16) | (buf[41]<<24)) + corr;
  268.           }
  269.           ++stop;
  270.         }
  271.       }
  272.       size -= (bufsize-21);
  273.     }
  274.   }
  275.  
  276.   if(start)
  277.     Seek(fh, start, OFFSET_BEGINNING);
  278.   ((ULONG *)buf)[0] = corr; /* store this for extract */
  279.   ((ULONG *)buf)[1] = start;
  280.  
  281.   return (BOOL) (start ? TRUE : FALSE);
  282. }
  283.  
  284. ULONG ExtractZIP(BPTR infh, BPTR outfh, STRPTR buf, ULONG filesize, ULONG buffersize)
  285. {
  286.   LONG start, corr, Type = 0, ret = 0, i;
  287.  
  288.   start = ((ULONG *)buf)[1];
  289.   corr = ((ULONG *)buf)[0]-start;
  290.  
  291.   while(Type != 0x504B0506 && !ret && !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C))
  292.   {
  293.     if(Read(infh, &Type, 4) == 4)
  294.     {
  295.       ret = RETURN_FAIL;
  296.       switch(Type)
  297.       {
  298.       case 0x504B0304: /* local */
  299.         if(Read(infh, buf+4, 26) == 26)
  300.         {
  301.           buf[0] = 'P'; buf[1] = 'K'; buf[2] = 3; buf[3] = 4;
  302.           if(Write(outfh, buf, 30) == 30)
  303.           {
  304.             ret = DoCopy(infh, outfh, buf, ((buf[18]) | (buf[19]<<8) | (buf[20]<<16) | (buf[21]<<24)) +
  305.             ((buf[26]) | (buf[27]<<8)) + ((buf[28]) | (buf[29]<<8)), buffersize);
  306.           }
  307.         }
  308.         break;
  309.       case 0x504B0102: /* central */
  310.         if(Read(infh, buf+4, 42) == 42)
  311.         {
  312.           buf[0] = 'P'; buf[1] = 'K'; buf[2] = 1; buf[3] = 2;
  313.           i = ((buf[42]) | (buf[43]<<8) | (buf[44]<<16) | (buf[45]<<24)) + corr;
  314.       buf[42] = i;
  315.       buf[43] = i>>8;
  316.       buf[44] = i>>16;
  317.       buf[45] = i>>24;
  318.           if(Write(outfh, buf, 46) == 46)
  319.           {
  320.             ret = DoCopy(infh, outfh, buf, ((buf[28]) | (buf[29]<<8)) +
  321.             ((buf[30]) | (buf[31]<<8)) + ((buf[32]) | (buf[33]<<8)), buffersize);
  322.           }
  323.         }
  324.         break;
  325.       case 0x504B0506: /* end */
  326.         if(Read(infh, buf+4, 18) == 18)
  327.         {
  328.           buf[0] = 'P'; buf[1] = 'K'; buf[2] = 5; buf[3] = 6;
  329.           i = ((buf[16]) | (buf[17]<<8) | (buf[18]<<16) | (buf[19]<<24)) + corr;
  330.       buf[16] = i;
  331.       buf[17] = i>>8;
  332.       buf[18] = i>>16;
  333.       buf[19] = i>>24;
  334.           if(Write(outfh, buf, 22) == 22)
  335.             ret = DoCopy(infh, outfh, buf, buf[20] | (buf[21]<<8), buffersize); /* copy comment */
  336.         }
  337.         break;
  338.       default:
  339.     Printf("Unknown or illegal data found.\n");
  340.     break;
  341.       }
  342.     }
  343.     else
  344.       Printf("Unexpected end of data.\n");
  345.   }
  346.   if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  347.     SetIoErr(ERROR_BREAK);
  348.  
  349.   return ret ? 0 : filesize-start;
  350. }
  351.  
  352. /******** exe2ace *********/
  353.  
  354. BOOL ScanACE(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  355. {
  356.   ULONG start = 0;
  357.   LONG i, pos = 0, stop = 0;
  358.  
  359.   while(size > 14 && !stop)
  360.   {
  361.     if(bufsize > size)
  362.       bufsize = size;
  363.     if(Seek(fh, pos, OFFSET_BEGINNING) < 0)
  364.       ++stop;
  365.     else if(Read(fh, buf, bufsize) != bufsize)
  366.       ++stop;
  367.     for(i = 0; i <= bufsize-14 && !stop; ++i)
  368.     {
  369.       if(buf[i+7] == '*' && buf[i+8] == '*' && buf[i+9] == 'A' && buf[i+10] == 'C' &&
  370.       buf[i+11] == 'E' && buf[i+12] == '*' && buf[i+13] == '*')
  371.       {
  372.         if(Seek(fh, -i, OFFSET_CURRENT) >= 0)
  373.           start = pos+i;
  374.         ++stop;
  375.       }
  376.     }
  377.     size -= i;
  378.     pos += i;
  379.   }
  380.  
  381.   if(start)
  382.     Seek(fh, start, OFFSET_BEGINNING);
  383.   ((ULONG *)buf)[0] = start;
  384.  
  385.   return (BOOL) (start ? TRUE : FALSE);
  386. }
  387.  
  388. ULONG ExtractACE(BPTR infh, BPTR outfh, STRPTR buf, ULONG filesize, ULONG buffersize)
  389. {
  390.   LONG ret;
  391.  
  392.   filesize -= ((ULONG *)buf)[0];
  393.   ret = DoCopy(infh, outfh, buf, filesize, buffersize);
  394.   
  395.   return ret ? 0 : filesize;
  396. }
  397.  
  398. /******** exe2rar *********/
  399.  
  400. BOOL ScanRAR(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  401. {
  402.   ULONG start = 0;
  403.   LONG i, pos = 0, stop = 0;
  404.  
  405.   while(size > 7 && !stop)
  406.   {
  407.     if(bufsize > size)
  408.       bufsize = size;
  409.     if(Seek(fh, pos, OFFSET_BEGINNING) < 0)
  410.       ++stop;
  411.     else if(Read(fh, buf, bufsize) != bufsize)
  412.       ++stop;
  413.     for(i = 0; i <= bufsize-7 && !stop; ++i)
  414.     {
  415.       if(buf[i] == 'R' && buf[i+1] == 'a' && buf[i+2] == 'r' && buf[i+3] == '!' &&
  416.       buf[i+4] == 0x1A && buf[i+5] == 7 && buf[i+6] == 0)
  417.       {
  418.         if(Seek(fh, -i, OFFSET_CURRENT) >= 0)
  419.           start = pos+i;
  420.         ++stop;
  421.       }
  422.     }
  423.     size -= i;
  424.     pos += i;
  425.   }
  426.  
  427.   if(start)
  428.     Seek(fh, start, OFFSET_BEGINNING);
  429.   ((ULONG *)buf)[0] = start;
  430.  
  431.   return (BOOL) (start ? TRUE : FALSE);
  432. }
  433.  
  434. /******** exe2cab *********/
  435.  
  436. BOOL ScanCAB(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  437. {
  438.   ULONG start = 0, len = 0, foff;
  439.   LONG i, pos = 0, stop = 0;
  440.  
  441.   while(size > 20 && !stop)
  442.   {
  443.     if(bufsize > size)
  444.       bufsize = size;
  445.     if(Seek(fh, pos, OFFSET_BEGINNING) < 0)
  446.       ++stop;
  447.     else if(Read(fh, buf, bufsize) != bufsize)
  448.       ++stop;
  449.     for(i = 0; i <= bufsize-20 && !stop; ++i)
  450.     {
  451.       if(buf[i] == 'M' && buf[i+1] == 'S' && buf[i+2] == 'C' && buf[i+3] == 'F')
  452.       {
  453.         len = (buf[i+8]) | (buf[i+9]<<8) | (buf[i+10]<<16) | (buf[i+11]<<24);
  454.         foff = (buf[i+16]) | (buf[i+17]<<8) | (buf[i+18]<<16) | (buf[i+19]<<24);
  455.         if(len <= size-i && foff < len)
  456.         {
  457.           if(Seek(fh, -i, OFFSET_CURRENT) >= 0)
  458.             start = pos+i;
  459.           ++stop;
  460.         }
  461.       }
  462.     }
  463.     size -= i;
  464.     pos += i;
  465.   }
  466.  
  467.   if(start)
  468.     Seek(fh, start, OFFSET_BEGINNING);
  469.   ((ULONG *)buf)[0] = len;
  470.  
  471.   return (BOOL) (start ? TRUE : FALSE);
  472. }
  473.  
  474. ULONG ExtractCAB(BPTR infh, BPTR outfh, STRPTR buf, ULONG filesize, ULONG buffersize)
  475. {
  476.   LONG ret;
  477.  
  478.   ret = DoCopy(infh, outfh, buf, (filesize = ((ULONG *)buf)[0]), buffersize);
  479.   
  480.   return ret ? 0 : filesize;
  481. }
  482.  
  483. /******** exe2arj *********/
  484.  
  485. BOOL ScanARJ(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  486. {
  487.   ULONG start = 0, len, cbuf[256], j, k, l;
  488.   LONG i, pos = 0, stop = 0;
  489.   STRPTR mem;
  490.  
  491.   while(size > 50 && !stop)
  492.   {
  493.     if(bufsize > size)
  494.       bufsize = size;
  495.     if(Seek(fh, pos, OFFSET_BEGINNING) < 0)
  496.       ++stop;
  497.     else if(Read(fh, buf, bufsize) != bufsize)
  498.       ++stop;
  499.     for(i = 0; i <= bufsize-50 && !stop; ++i)
  500.     {
  501.       if(buf[i] == 0x60 && buf[i+1] == 0xEA)
  502.       {
  503.         len = (buf[i+2]) | (buf[i+3]<<8);
  504.         if(size-i > len+4)
  505.         {
  506.           if(bufsize-i < len+4)
  507.             break;
  508.           else
  509.           {
  510.             for(l = 0; l < 256; ++l)
  511.             {
  512.               k = l;
  513.  
  514.               for(j = 0; j < 8; ++j)
  515.               {
  516.                 if(k & 1)
  517.                   k = (k >> 1) ^ 0xEDB88320;
  518.                 else
  519.                   k >>= 1;
  520.               }
  521.               cbuf[l] = k;
  522.             }
  523.             l = ~0;
  524.             k = len;
  525.             mem = buf+i+4;
  526.  
  527.             while(k--)
  528.               l = cbuf[(l ^ *mem++) & 0xFF] ^ (l >> 8);
  529.             if(~l == ((mem[0]) | (mem[1]<<8) | (mem[2]<<16) | (mem[3]<<24)))
  530.             {
  531.               if(Seek(fh, -i, OFFSET_CURRENT) >= 0)
  532.                 start = pos+i;
  533.               ++stop;
  534.             }
  535.           }
  536.         }
  537.       }
  538.     }
  539.     size -= i;
  540.     pos += i;
  541.   }
  542.  
  543.   if(start)
  544.     Seek(fh, start, OFFSET_BEGINNING);
  545.   ((ULONG *)buf)[0] = start;
  546.  
  547.   return (BOOL) (start ? TRUE : FALSE);
  548. }
  549.  
  550. /******** exe2lha *********/
  551.  
  552. BOOL ScanLHA(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  553. {
  554.   ULONG start = 0;
  555.  
  556.   if(Read(fh, buf, 100) < 0)
  557.     return 0;
  558.   if(!buf[0] && !buf[1] && buf[2] == 3 && buf[3] == 0xF3 && buf[44] == 'S'
  559.   && buf[45] == 'F' && buf[46] == 'X' && buf[47] == '!')
  560.   {
  561.     start = (buf[55]) | (buf[54]<<8) | (buf[53]<<16) | (buf[52]<<24);
  562.     if(Seek(fh, start, OFFSET_BEGINNING) < 0)
  563.       start = 0;
  564.   }
  565.  
  566.   if(start)
  567.     Seek(fh, start, OFFSET_BEGINNING);
  568.   ((ULONG *)buf)[0] = start;
  569.  
  570.   return (BOOL) (start ? TRUE : FALSE);
  571. }
  572.  
  573. /******** exe2lzh *********/
  574.  
  575. BOOL ScanLZH(BPTR fh, STRPTR buf, ULONG size, ULONG bufsize)
  576. {
  577.   ULONG start = 0;
  578.   LONG i, pos = 0, stop = 0;
  579.  
  580.   while(size > 21 && !stop)
  581.   {
  582.     if(bufsize > size)
  583.       bufsize = size;
  584.     if(Seek(fh, pos, OFFSET_BEGINNING) < 0)
  585.       ++stop;
  586.     else if(Read(fh, buf, bufsize) != bufsize)
  587.       ++stop;
  588.     for(i = 0; i <= bufsize-21 && !stop; ++i)
  589.     {
  590.       if(buf[i+2] == '-' && buf[i+3] == 'l' && (buf[i+4] == 'h' || buf[i+4] == 'z') &&
  591.       buf[i+6] == '-' && buf[20] <= 2)
  592.       {
  593.         if(Seek(fh, -i, OFFSET_CURRENT) >= 0)
  594.           start = pos+i;
  595.         ++stop;
  596.       }
  597.     }
  598.     size -= i;
  599.     pos += i;
  600.   }
  601.  
  602.   if(start)
  603.     Seek(fh, start, OFFSET_BEGINNING);
  604.   ((ULONG *)buf)[0] = start;
  605.  
  606.   return (BOOL) (start ? TRUE : FALSE);
  607. }
  608.  
  609. /**************************/
  610.  
  611. struct ScanData ScanFuncs[] = {
  612. {ScanZIP, ExtractZIP, "zip", "Zip"},
  613. {ScanACE, ExtractACE, "ace", "Ace"},
  614. {ScanRAR, ExtractACE, "rar", "Rar"}, /* reuse ExtractACE */
  615. {ScanCAB, ExtractCAB, "cab", "Cabinet"},
  616. {ScanARJ, ExtractACE, "arj", "Arj"}, /* reuse ExtractACE */
  617. {ScanLHA, ExtractACE, "lha", "LhA"}, /* reuse ExtractACE */
  618. {ScanLZH, ExtractACE, "lzh", "Amiga-LhA"}, /* reuse ExtractACE */
  619. {0,0},
  620. };
  621.  
  622.